﻿using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using Windows.Storage;

namespace Monaco.MonacoHandler;
public static class WebResourceHelper
{
    private static readonly object ExtractionLock = new();
    private static readonly string ResourceBasePath = "Monaco.monaco_editor.";
    public static string ResourceFolderName { get; set; } = "monaco-editor";

    public static string GetResourceDirectory(string targetFolder = null)
    {
        // 允许动态设置目标文件夹
        var finalFolder = targetFolder ?? ResourceFolderName;

        try
        {
            // 获取沙盒内的应用数据文件夹
            StorageFolder localFolder = ApplicationData.Current.LocalFolder;
            string appResourcesPath = Path.Combine(localFolder.Path, finalFolder);

            // 安全创建目录
            if (!Directory.Exists(appResourcesPath))
            {
                Directory.CreateDirectory(appResourcesPath);
            }
            // 检查资源版本标记
            string versionFile = Path.Combine(appResourcesPath, ".resourceversion");
            var assemblyVersion = Assembly.GetExecutingAssembly().GetName().Version.ToString();

            // 检查是否需要重新提取
            bool needExtraction = !File.Exists(versionFile) ||
                                  File.ReadAllText(versionFile) != assemblyVersion;

            if (needExtraction)
            {
                Log($"需要提取新版本资源: {assemblyVersion}");
                ExtractResources(appResourcesPath);

                // 标记版本号
                File.WriteAllText(versionFile, assemblyVersion);
            }

            return appResourcesPath;
        }
        catch (Exception ex)
        {
            LogError($"获取资源目录失败: {ex.Message}");
            return GetFallbackResourcePath(finalFolder);
        }
    }
    private static void ExtractResources(string targetDir)
    {
        // 确保单线程提取资源
        lock (ExtractionLock)
        {
            try
            {
                var assembly = Assembly.GetExecutingAssembly();

                // 查找所有匹配资源
                var resourceNames = assembly
                    .GetManifestResourceNames()
                    .Where(r => r.StartsWith(ResourceBasePath))
                    .ToList();

                if (!resourceNames.Any())
                {
                    LogWarning("未找到任何嵌入资源！");
                    return;
                }

                Log($"开始提取 {resourceNames.Count} 个资源到: {targetDir}");
                foreach (string resourceName in resourceNames)
                {
                    string relativePath = resourceName.Substring(ResourceBasePath.Length);

                    // 移除开头的路径分隔符（如果有）
                    relativePath = relativePath.TrimStart('\\', '/');

                    // 处理可能的前导点
                    relativePath = HandleLeadingDots(relativePath);

                    string filePath = Path.Combine(targetDir, relativePath);
                    string dirPath = Path.GetDirectoryName(filePath);

                    // 创建必要目录
                    if (!Directory.Exists(dirPath) && !string.IsNullOrEmpty(dirPath))
                    {
                        Directory.CreateDirectory(dirPath);
                    }

                    // 写入文件
                    using var stream = assembly.GetManifestResourceStream(resourceName);
                    if (stream == null)
                    {
                        LogWarning($"无法读取资源流: {resourceName}");
                        continue;
                    }

                    using var fileStream = File.Create(filePath);
                    stream.CopyTo(fileStream);

                    Log($"提取: {relativePath}");
                }

                Log("资源提取完成！");
            }
            catch (Exception ex)
            {
                LogError($"资源提取失败: {ex}");
                throw;
            }
        }
    }

    private static string HandleLeadingDots(string path)
    {
        // 处理文件名开头的点（例如 .editorconfig）
        if (path.StartsWith("."))
        {
            return "dot_" + path.Substring(1);
        }
        return path;
    }

    private static string GetFallbackResourcePath(string folderName)
    {
        try
        {
            // 尝试应用安装目录
            string installPath = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
            if (!string.IsNullOrEmpty(installPath))
            {
                var path = Path.Combine(installPath, folderName);
                if (Directory.Exists(path))
                {
                    return path;
                }
            }

            // 最后使用临时目录
            return Path.Combine(Path.GetTempPath(), folderName);
        }
        catch
        {
            return Environment.GetFolderPath(
                Environment.SpecialFolder.LocalApplicationData);
        }
    }

    private static void Log(string message)
    {
        Debug.WriteLine($"[WebResourceHelper] {message}");
    }

    private static void LogWarning(string message)
    {
        Debug.WriteLine($"[WARNING] [WebResourceHelper] {message}");
    }

    private static void LogError(string message)
    {
        Debug.WriteLine($"[ERROR] [WebResourceHelper] {message}");
        // 考虑使用 Application.Current.Diagnostics 记录错误
    }
}